package com.ruoyi.project.bus.register.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.text.Convert;
import com.ruoyi.project.bus.compare.domain.BusCompare;
import com.ruoyi.project.bus.compare.mapper.BusCompareMapper;
import com.ruoyi.project.bus.register.domain.BusRegister;
import com.ruoyi.project.bus.register.mapper.BusRegisterMapper;
import com.ruoyi.project.bus.register.service.IBusRegisterService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 登录信息增删改查Service业务层处理
 *
 * @author ruoyi
 * @date 2020-11-26
 */
@Service
public class BusRegisterServiceImpl implements IBusRegisterService {
    @Autowired
    private BusRegisterMapper busRegisterMapper;
    @Autowired
    private BusCompareMapper busCompareMapper;
    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 查询登录信息增删改查
     *
     * @param id 登录信息增删改查ID
     * @return 登录信息增删改查
     */
    @Override
    public BusRegister selectBusRegisterById(Long id, String type) {
        return busRegisterMapper.selectBusRegisterById(id, getTable(type));
    }

    /**
     * 查询登录信息增删改查列表
     *
     * @param busRegister 登录信息增删改查
     * @return 登录信息增删改查
     */
    @Override
    public List<BusRegister> selectBusRegisterList(BusRegister busRegister, String type) {
        return busRegisterMapper.selectBusRegisterList(busRegister, getTable(type));
    }

    /**
     * 新增登录信息增删改查
     *
     * @param busRegister 登录信息增删改查
     * @return 结果
     */
    @Override
    public int insertBusRegister(BusRegister busRegister, String type) {
        return busRegisterMapper.insertBusRegister(busRegister, getTable(type));
    }

    /**
     * 修改登录信息增删改查
     *
     * @param busRegister 登录信息增删改查
     * @return 结果
     */
    @Override
    public int updateBusRegister(BusRegister busRegister, String type) {
        return busRegisterMapper.updateBusRegister(busRegister, getTable(type));
    }

    /**
     * 删除登录信息增删改查对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteBusRegisterByIds(String ids, String type) {
        return busRegisterMapper.deleteBusRegisterByIds(Convert.toStrArray(ids), getTable(type));
    }

    /**
     * 删除登录信息增删改查信息
     *
     * @param id 登录信息增删改查ID
     * @return 结果
     */
    @Override
    public int deleteBusRegisterById(Long id) {
        return busRegisterMapper.deleteBusRegisterById(id, "gs");
    }

    @Override
    public String importUser(List<BusRegister> registerList, boolean updateSupport, String type) {
        if (CollectionUtils.isEmpty(registerList)) {
            return "导入的数据为空";
        }
        int failureNum = 0;
        for (BusRegister busRegister : registerList) {
            BusRegister register = busRegisterMapper.findBySbh(busRegister.getSbh(), getTable(type));
            if (null == register) {
                this.insertBusRegister(busRegister, type);
            } else if (updateSupport) {
                this.busRegisterMapper.updateBusRegisterByBsh(busRegister, getTable(type));
            } else {
                failureNum++;
            }
        }
        return "导入数据，成功" + (registerList.size() - failureNum) + "条，失败" + failureNum + "条。";
    }

    @Override
    public List<BusRegister> compareData(Long compareId) {
        BusCompare busCompare = busCompareMapper.selectBusCompareById(compareId);
        if (null == busCompare) {
            return null;
        }

        JSONArray columnsArray = JSON.parseArray(busCompare.getRuleColumns());
        List<String> columnList = new ArrayList<>();
        for (Object o : columnsArray) {
            if (o instanceof String) {
                JSONObject jsonObject = JSON.parseObject((String) o);
                String columnItem = jsonObject.getString("column");
                columnList.add(columnItem);
            }
            if (o instanceof JSONObject) {
                String columnItem = ((JSONObject) o).getString("column");
                columnList.add(columnItem);
            }
        }
        String querySql = this.genQueryCompareData(busCompare.getRuleTables(), columnList);
        List<BusRegister> busRegisters = jdbcTemplate.query(querySql, (resultSet, i) -> {
            BusRegister busRegister = new BusRegister();
            busRegister.setBsrdh(resultSet.getString("bsrdh"));
            busRegister.setBsrgddh(resultSet.getString("bsrgddh"));
            busRegister.setBsrsfzh(resultSet.getString("bsrsfzh"));
            busRegister.setBsrxm(resultSet.getString("bsrxm"));
            busRegister.setCwfzrdh(resultSet.getString("cwfzrdh"));
            busRegister.setCwfzrgddh(resultSet.getString("cwfzrgddh"));
            busRegister.setCwfzrxm(resultSet.getString("cwfzrxm"));
            busRegister.setDjhlb(resultSet.getString("djhlb"));
            busRegister.setDjrq(resultSet.getString("djrq"));
            busRegister.setDjzclx(resultSet.getString("djzclx"));
            busRegister.setDwlsgx(resultSet.getString("dwlsgx"));
            busRegister.setFrdh(resultSet.getString("frdh"));
            busRegister.setFrgddh(resultSet.getString("frgddh"));
            busRegister.setFrmc(resultSet.getString("frmc"));
            busRegister.setFrsfzh(resultSet.getString("frsfzh"));
            busRegister.setGdghlx(resultSet.getString("gdghlx"));
            busRegister.setHy(resultSet.getString("hy"));
            busRegister.setId(resultSet.getLong("id"));
            busRegister.setKqcwsztdjbz(resultSet.getString("kqcwsztdjbz"));
            busRegister.setKzztdjlx(resultSet.getString("kzztdjlx"));
            busRegister.setNsrmc(resultSet.getString("nsrmc"));
            busRegister.setNsrzt(resultSet.getLong("nsrzt"));
            busRegister.setSbh(resultSet.getString("sbh"));
            busRegister.setScjydz(resultSet.getString("scjydz"));
            busRegister.setShxydm(resultSet.getString("shxydm"));
            busRegister.setSsdabh(resultSet.getString("ssdabh"));
            busRegister.setSsgly(resultSet.getString("ssgly"));
            busRegister.setSsjdbsc(resultSet.getString("ssjdbsc"));
            busRegister.setYxbz(resultSet.getString("yxbz"));
            busRegister.setZcdz(resultSet.getString("zcdz"));
            busRegister.setZgswjg(resultSet.getString("zgswjg"));
            busRegister.setZgsws(resultSet.getString("zgsws"));
            busRegister.setZzjgdm(resultSet.getString("zzjgdm"));
            return busRegister;
        });
        return busRegisters;
    }

    private String getTable(String type) {
        String table = "";
        switch (type) {
            case "sq":
                table = "bus_register_sq";
                break;
            case "sw":
                table = "bus_register_sw";
                break;
            default:
                table = "bus_register";
        }
        return table;
    }

    private String genQueryCompareData(String ruleTables, List<String> columns) {
        // [{'table': 'www', 'label':'www', 'flag':'has/no'}]
        JSONArray ruleTableArray = JSON.parseArray(ruleTables);
        StringBuilder resBuilder = new StringBuilder("select * from (");
        List<String> whereTableList = new ArrayList<>();
        List<String> onTableList = new ArrayList<>();
        for (Object o : ruleTableArray) {
            JSONObject item = null;
            if (o instanceof String) {
                item = JSON.parseObject((String) o);
            }
            if (o instanceof JSONObject) {
                item = (JSONObject) o;
            }
            if (null != item) {
                if ("has".equals(item.getString("flag"))) {
                    onTableList.add(item.getString("table"));
                }
                if ("no".equals(item.getString("flag"))) {
                    whereTableList.add(item.getString("table"));
                }
            }
        }
        StringBuilder joinTableBuilder = new StringBuilder();
        for (String item : onTableList) {
            if (joinTableBuilder.length() < 1) {
                joinTableBuilder.append("select " ).append(item).append(".*").append(" from ").append(item);
            } else {
                joinTableBuilder.append(", ").append(item);
            }
        }
        if (onTableList.size() > 1) {
            joinTableBuilder.append(" where ");
            List<String> where = new ArrayList<>();
            combinationSelect(onTableList.toArray(new String[onTableList.size()]),2, where);
            StringBuilder whereBuilder = new StringBuilder();
            for (String column : columns) {
                for (String whereItem : where) {
                    String[] whereItemArray = whereItem.split(",");
                    if (whereBuilder.length() > 0) {
                        whereBuilder.append(" and ");
                    }
                    whereBuilder.append(whereItemArray[0]).append(".").append(column).append("=").append(whereItemArray[1])
                            .append(".").append(column);
                }
            }
            joinTableBuilder.append(whereBuilder);
        }
        resBuilder.append(joinTableBuilder).append(" ) t");

        if (whereTableList.size() > 0) {
            resBuilder.append(" where ");
            StringBuilder wBuilder = new StringBuilder();
            for (String wItem : whereTableList) {
                if (wBuilder.length() > 0){
                    wBuilder.append(" and ");
                }
                wBuilder.append(" not EXISTS ( select 1 from ").append(wItem).append(" where ");
                StringBuilder cItem = new StringBuilder();
                for (String column : columns) {
                    if (cItem.length() > 0) {
                        cItem.append(" and ");
                    }
                    cItem.append(wItem).append(".").append(column).append("= t.").append(column);
                }
                wBuilder.append(cItem).append(") ");
            }
            resBuilder.append(wBuilder);
        }
        return resBuilder.toString();
    }

    public static void combinationSelect(String[] dataList, int n, List<String> res) {
        combinationSelect(dataList, 0, new String[n], 0, res);
    }

    private static void combinationSelect(String[] dataList, int dataIndex, String[] resultList, int resultIndex, List<String> res) {
        int resultLen = resultList.length;
        int resultCount = resultIndex + 1;
        // 全部选择完时，输出组合结果
        if (resultCount > resultLen) {
            StringBuilder item = new StringBuilder();
            for (String rItem : resultList) {
                if (item.length() > 0) {
                    item.append(",");
                }
                item.append(rItem);
            }
            res.add(item.toString());
            return;
        }
        // 递归选择下一个
        for (int i = dataIndex; i < dataList.length + resultCount - resultLen; i++) {
            resultList[resultIndex] = dataList[i];
            combinationSelect(dataList, i + 1, resultList, resultIndex + 1, res);
        }
    }
}
